using System;
using System.Collections.Generic;
using System.Text;

using VistaDB.DDA;

namespace NSimpleDB.Service.VistaDb.Managers
{
    internal class SchemaManager : IDisposable
    {
        private string filename;
        private IVistaDBDDA dda;
        private IVistaDBDatabase db;


        public SchemaManager(string filename)
        {
            this.filename = filename;

            this.dda = VistaDBEngine.Connections.OpenDDA();
            if (System.IO.File.Exists(filename))
            {
                this.db = dda.OpenDatabase(this.filename, VistaDB.VistaDBDatabaseOpenMode.NonexclusiveReadWrite, null);
            }
            else
            {
                this.db = dda.CreateDatabase(this.filename, false, null, 0, 0, false);

                #region Create domain directory table
                IVistaDBTableSchema tbSchema = this.db.NewTable("DomainDirectory");

                tbSchema.AddColumn("idDomain", VistaDB.VistaDBType.Int);
                tbSchema.DefineColumnAttributes("idDomain", false, false, false, false, null, null);
                tbSchema.DefineIdentity("idDomain", "0", "1");
                tbSchema.DefineIndex("PK", "idDomain", true, true);

                tbSchema.AddColumn("domainName", VistaDB.VistaDBType.VarChar);
                tbSchema.DefineColumnAttributes("domainName", false, false, false, false, null, null);
                tbSchema.DefineIndex("domainNameIndex", "domainName", false, true);

                tbSchema.AddColumn("scheduledForDeletion", VistaDB.VistaDBType.Bit);
                tbSchema.DefineColumnAttributes("scheduledForDeletion", false, false, false, false, null, null);
                tbSchema.DefineIndex("scheduledForDeletionIndex", "scheduledForDeletion", false, false);

                this.db.CreateTable(tbSchema, false, false).Close();
                #endregion
            }
        }


        public IVistaDBDatabase Database
        {
            get { return this.db; }
        }


        public IVistaDBTable OpenDomainDirectoryTable()
        {
            return this.db.OpenTable("DomainDirectory", false, false);
        }


        public void CreateDomainTable(int idDomain)
        {
            #region create domain table
            IVistaDBTableSchema tbSchema = this.db.NewTable(this.DomainTableNameFromId(idDomain));
            tbSchema.AddColumn("itemName", VistaDB.VistaDBType.NVarChar);
            tbSchema.DefineColumnAttributes("itemName", false, true, false, false, null, null);

            tbSchema.AddColumn("attributeName", VistaDB.VistaDBType.NVarChar);
            tbSchema.DefineColumnAttributes("attributeName", false, true, false, false, null, null);

            tbSchema.AddColumn("attributeValue", VistaDB.VistaDBType.NVarChar);
            tbSchema.DefineColumnAttributes("attributeValue", false, false, false, false, null, null);

            tbSchema.DefineIndex("PK", "itemName; attributeName; attributeValue", true, true);
            tbSchema.DefineIndex("attributeIndex", "attributeName; attributeValue", false, false);
            this.db.CreateTable(tbSchema, false, false).Close();
            #endregion
        }


        public IVistaDBTable OpenDomainTable(int idDomain)
        {
            return this.db.OpenTable(this.DomainTableNameFromId(idDomain), false, false);
        }


        public void DropDomainTable(int idDomain)
        {
            // delete domain table
            this.db.DropTable(this.DomainTableNameFromId(idDomain));
        }


        public string DomainTableNameFromId(int idDomain)
        {
            return string.Format("Domain{0}", idDomain);
        }


        #region IDisposable Members

        public void Dispose()
        {
            this.db.Close();
            this.dda.Dispose();
        }

        #endregion
    }
}
